package main

import (
	"strconv"
	"time"

	mgo "gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"

	"server/src/gps"
)

type MileageStatics struct {
	cfg *Config
	dbo *DBOperation
}

func NewMileageStatics(cfg *Config, dbo *DBOperation) *MileageStatics {
	ms := MileageStatics{cfg: cfg, dbo: dbo}
	return &ms
}

func (p *MileageStatics) Do() {
	trackDate := p.getTrackDate()

	zLog(nil, "开始统计", trackDate, "的里程")
	tStart := time.Now().Unix()

	defer func() {
		t := time.Now().Unix() - tStart

		zLog(nil, "统计里程结束，耗时：", t, "秒")
	}()

	var _id bson.ObjectId

	for {
		rids, err := p.dbo.getReceivers(_id, 10)
		if err != nil {
			if err == mgo.ErrNotFound {
				zLog(nil, "已经处理完成")
			} else {
				zLog(nil, "统计出错：", err.Error())
			}
		}
		ridsCount := len(rids)
		if ridsCount == 0 {
			zLog(nil, "已经处理完成")
			time.Sleep(10 * time.Second)
		} else {
			zLog(nil, "读入", ridsCount, "条数据")
			for k, v := range rids {
				_id = v.ID_
				zLog(nil, "开始处理 ", k, "/", ridsCount, " 条纪录：", v.Rid)

				p.CalcReceiverMileage(v.Rid, trackDate)
			}
		}

		time.Sleep(time.Second)
	}
}

func (p *MileageStatics) getTrackDate() int {
	t := time.Now().AddDate(0, 0, -1)
	st := t.Format("060102")
	ret, _ := strconv.Atoi(st)
	return ret
}

func (p *MileageStatics) CalcReceiverMileage(rid string, trackDate int) {
	var tr TrackResultT
	var err error

	tr.Tracks, err = p.dbo.receiverTrack(rid, trackDate)
	if err != nil {
		zLog(nil, "receiverTrack函数出错：", err.Error(), "；参数为：", rid, ",", trackDate)
		return
	}
	tr.CalcMileage()

	if tr.Mileage > 0.0 {
		p.dbo.saveMileage(rid, trackDate, tr.Mileage)

		p.dbo.saveTotalMileage(rid, tr.Mileage)
	}
}

type TrackResultT struct {
	Mileage float64     `json:"mileage"`
	Tracks  []LocationT `json:"tracks"`
}

func (p *TrackResultT) CalcMileage() {
	var g gps.GPS
	p.Mileage = 0.0
	if p.Tracks == nil || len(p.Tracks) == 0 {
		return
	}

	var lastLat, lastLng float64
	for _, v := range p.Tracks {
		if lastLat == 0.0 && lastLng == 0.0 {
			lastLat, lastLng = v.Lat, v.Lng
		} else {
			p.Mileage += g.Distance(v.Lat, v.Lng, lastLat, lastLng)
			lastLat, lastLng = v.Lat, v.Lng
		}
	}

}
